using System;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using SpImageCacheSolution.SPImageCacheEventReceiver;

namespace SpImageCacheSolution.Features.Feature1
{
    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>

    [Guid("e12ff3e9-86f0-4061-92fa-4e0104813398")]
    public class Feature1EventReceiver : SPFeatureReceiver
    {
        private readonly ModificationEntry[] _childNodeEntries = 
        {        
         new ModificationEntry("add[@name='SpImageCacheHttpModule']", "configuration/system.webServer/modules",@"<add name=""SpImageCacheHttpModule"" type=""SpImageCacheHttpModule.SpImageCacheHttpModule, SpImageCacheHttpModule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=aa949d4781fbc8c1"" />")
        };


        public void RegisterHttpHandler(SPFeatureReceiverProperties properties)
        {
            SPWebService spWebService = SPFarm.Local.Services.GetValue<SPWebService>();

            if (spWebService != null)
            {
                SPWebApplicationCollection spWebApplicationCollection = spWebService.WebApplications;

                foreach (SPWebApplication spWebApplication in spWebApplicationCollection)
                {
                    foreach (ModificationEntry entry in _childNodeEntries)
                    {
                        spWebApplication.WebConfigModifications.Add(CreateModification(entry.Name, entry.XPath, entry.Value, SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode));
                    }

                    spWebService.ApplyWebConfigModifications();
                }
            }
        }

        public void UnRegisterHttpHandler(SPFeatureReceiverProperties properties)
        {
            SPWebService spWebService = SPFarm.Local.Services.GetValue<SPWebService>();

            if (spWebService != null)
            {
                SPWebApplicationCollection spWebApplicationCollection = spWebService.WebApplications;

                foreach (SPWebApplication spWebApplication in spWebApplicationCollection)
                {
                    foreach (ModificationEntry entry in _childNodeEntries)
                    {
                        spWebApplication.WebConfigModifications.Remove(CreateModification(entry.Name, entry.XPath, entry.Value, SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode));
                    }

                    SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
                }
            }
        }

        private struct ModificationEntry
        {
            public readonly string Name;

            public readonly string XPath;

            public readonly string Value;

            public ModificationEntry(string name, string xPath, string value)
            {
                Name = name;

                XPath = xPath;

                Value = value;
            }
        }
        
        public SPWebConfigModification CreateModification(string name, string xPath, string value, SPWebConfigModification.SPWebConfigModificationType type)
        {
            return new SPWebConfigModification(name, xPath)
                                                                  {
                                                                      Owner = "Global Config Management",
                                                                      Sequence = 0,
                                                                      Type = type,
                                                                      Value = value
                                                                  };
        }
        
        private const string SpImagecacheLibraryName = "imagecache";

        private const string SpImagecacheLibraryDescription = "This is SPImageCache library. It holds modifiyed images.";

        private static void AddImageCacheLibraryEventHandlers(SPList spList)
        {
            Type spImageCacheEventReceiverType = typeof(SpImageCacheEventReceiver);

            SPEventReceiverDefinition spEventReceiverDefinition = spList.EventReceivers.Add();

            spEventReceiverDefinition.Name = "SpImageCacheEventReceiver";

            spEventReceiverDefinition.Type = SPEventReceiverType.ItemAdded;

            spEventReceiverDefinition.Assembly = spImageCacheEventReceiverType.Assembly.FullName;

            spEventReceiverDefinition.Class = spImageCacheEventReceiverType.FullName;

            spEventReceiverDefinition.SequenceNumber = 1000;

            spEventReceiverDefinition.Data = string.Empty;

            spEventReceiverDefinition.Update();

            spList.Update();
        }

        private static SPList CreateImageCacheLibrary(SPWeb spWeb)
        {
            DeleteImageCacheLibrary(spWeb);

            Guid imageCacheLibraryGuid = spWeb.Lists.Add(SpImagecacheLibraryName, SpImagecacheLibraryDescription, SPListTemplateType.PictureLibrary);

            spWeb.Update();

            SPList spList = spWeb.Lists[imageCacheLibraryGuid];

            spList.Fields.Add("OrigModified", SPFieldType.DateTime, true);

            spList.Update();

            return spList;
        }

        private static void DeleteImageCacheLibrary(SPWeb spWeb)
        {
            SPList spList = spWeb.Lists.TryGetList(SpImagecacheLibraryName);

            if (spList != null)
                spList.Delete();
        }

        private static void AddUserCustomActions(SPList spList)
        {
            SPUserCustomAction spUserCustomAction = spList.UserCustomActions.Add();

            spUserCustomAction.Title = "SpImageCache settings";

            spUserCustomAction.Description = "Configure SpImageCache actions and presets";

            spUserCustomAction.Location = "Microsoft.SharePoint.ListEdit";

            spUserCustomAction.Group = "GeneralSettings";

            spUserCustomAction.Rights = SPBasePermissions.ApproveItems;

            spUserCustomAction.Url = "_layouts/SpImageCacheSolution/SpImageCacheSettingsPage.aspx";

            spUserCustomAction.Update();
        }

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPWeb spWeb = properties.Feature.Parent as SPWeb;

            if (spWeb != null)
            {
                SPList spList = CreateImageCacheLibrary(spWeb);

                AddImageCacheLibraryEventHandlers(spList);

                AddUserCustomActions(spList);

                RegisterHttpHandler(properties);
            }
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPWeb spWeb = properties.Feature.Parent as SPWeb;

            if (spWeb != null)
            {
                DeleteImageCacheLibrary(spWeb);

                UnRegisterHttpHandler(properties);
            }
        }
    }
}
